//
// Created by jsjxsy on 2022/8/17.
//
#include <iostream>
#include <cstdio>
using namespace std;
class Base {
 public:
//  Base(){}
//  Base(Base const&){}
  friend bool operator==(const Base &lhs, const Base &rhs);
 protected:
  virtual bool equals(const Base &rhs) const;
};
bool Base::equals(const Base &rhs) const {
  //return this == rhs;
  return false;
}
class Derived : public Base {
  friend bool operator==(const Base &lhs, const Base &rhs);
 public:
//  Derived() {}
//  Derived(string name) : name(name) {
//  }
  bool equals(const Base &rhs) const;
  void setName(const string &name) {
    this->name = name;
  }
 private:
  string name;
};

bool operator==(const Base &lhs, const Base &rhs) {
  return typeid(lhs) == typeid(rhs) && lhs.equals(rhs);
}

bool Derived::equals(const Base &rhs) const {
  try {
    auto r = dynamic_cast<const Derived &>(rhs);
    return r.name == name;
  } catch (bad_cast &e) {
    cerr << "Base cast Deried class error" << endl;
  }
  return false;
}

int main() {
  Derived d1;
  Derived d2;
  d1.setName("lisi");
  d2.setName("lisi");
  if (d1.equals(d2)) {
    cout << "d1 == d2" << endl;
  }
  return 0;
}